/**
 * Yolema.com Inc.
 * Copyright (c) 2011-2012 All Rights Reserved.
 */
package org.grayrabbit.pay.chinapnr.params;

import org.apache.commons.lang.StringUtils;
import org.grayrabbit.pay.CheckUtil;
import org.grayrabbit.pay.chinapnr.Chinapnr;
import org.grayrabbit.pay.chinapnr.common.ChinapnrGate;
import org.grayrabbit.pay.chinapnr.common.PnrConstants;
import org.grayrabbit.pay.chinapnr.config.ChinapnrConfigUtil;
import org.grayrabbit.pay.chinapnr.config.ChinapnrInfo;

/**
 * 提交的表单
 * 
 * @author wy
 * @version $Id: ChinapnrForm.java, v 0.1 2012-11-4 下午5:58:20 wy Exp $
 */
public class ChinapnrPayForm {

    /**交易ID*/
    private String       tradeId;

    /**交易金额 必须两位小数*/
    private String       money;

    /**网关 */
    private ChinapnrGate gate;

    /**MerPriv 备注*/
    private String       merPriv;

    /**银行卡号 变长 19位*/
    private String       cardNo;

    /**银行卡有效期 定长4位*/
    private String       validDate;

    /**银行卡Cvv2码 定长3位*/
    private String       cvv2;

    /**00 -- 身份证*/
    private String       idType = "00";

    /**证件号*/
    private String       idNo;

    /**卡所属人的姓名*/
    private String       name;

    /**手机号码 招行两通模式，网关号为Tc*/
    private String       mobNo;

    /**
     * Getter method for property <tt>tradeId</tt>.
     * 
     * @return property value of tradeId
     */
    public String getTradeId() {
        return tradeId;
    }

    /**
     * Setter method for property <tt>tradeId</tt>.
     * 
     * @param tradeId value to be assigned to property tradeId
     */
    public void setTradeId(String tradeId) {
        this.tradeId = tradeId;
    }

    /**
     * Getter method for property <tt>money</tt>.
     * 
     * @return property value of money
     */
    public String getMoney() {
        return money;
    }

    /**
     * Setter method for property <tt>money</tt>.
     * 
     * @param money value to be assigned to property money
     */
    public void setMoney(String money) {
        this.money = money;
    }

    /**
     * Getter method for property <tt>gate</tt>.
     * 
     * @return property value of gate
     */
    public ChinapnrGate getGate() {
        return gate;
    }

    /**
     * Setter method for property <tt>gate</tt>.
     * 
     * @param gate value to be assigned to property gate
     */
    public void setGate(ChinapnrGate gate) {
        this.gate = gate;
    }

    /**
     * Getter method for property <tt>merPriv</tt>.
     * 
     * @return property value of merPriv
     */
    public String getMerPriv() {
        return merPriv;
    }

    /**
     * Setter method for property <tt>merPriv</tt>.
     * 
     * @param merPriv value to be assigned to property merPriv
     */
    public void setMerPriv(String merPriv) {
        this.merPriv = merPriv;
    }

    /**
     * Getter method for property <tt>cardNo</tt>.
     * 
     * @return property value of cardNo
     */
    public String getCardNo() {
        return cardNo;
    }

    /**
     * Setter method for property <tt>cardNo</tt>.
     * 
     * @param cardNo value to be assigned to property cardNo
     */
    public void setCardNo(String cardNo) {
        this.cardNo = cardNo;
    }

    /**
     * Getter method for property <tt>validDate</tt>.
     * 
     * @return property value of validDate
     */
    public String getValidDate() {
        return validDate;
    }

    /**
     * Setter method for property <tt>validDate</tt>.
     * 
     * @param validDate value to be assigned to property validDate
     */
    public void setValidDate(String validDate) {
        this.validDate = validDate;
    }

    /**
     * Getter method for property <tt>cvv2</tt>.
     * 
     * @return property value of cvv2
     */
    public String getCvv2() {
        return cvv2;
    }

    /**
     * Setter method for property <tt>cvv2</tt>.
     * 
     * @param cvv2 value to be assigned to property cvv2
     */
    public void setCvv2(String cvv2) {
        this.cvv2 = cvv2;
    }

    /**
     * Getter method for property <tt>idType</tt>.
     * 
     * @return property value of idType
     */
    public String getIdType() {
        return idType;
    }

    /**
     * Setter method for property <tt>idType</tt>.
     * 
     * @param idType value to be assigned to property idType
     */
    public void setIdType(String idType) {
        this.idType = idType;
    }

    /**
     * Getter method for property <tt>idNo</tt>.
     * 
     * @return property value of idNo
     */
    public String getIdNo() {
        return idNo;
    }

    /**
     * Setter method for property <tt>idNo</tt>.
     * 
     * @param idNo value to be assigned to property idNo
     */
    public void setIdNo(String idNo) {
        this.idNo = idNo;
    }

    /**
     * Getter method for property <tt>name</tt>.
     * 
     * @return property value of name
     */
    public String getName() {
        return name;
    }

    /**
     * Setter method for property <tt>name</tt>.
     * 
     * @param name value to be assigned to property name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Getter method for property <tt>mobNo</tt>.
     * 
     * @return property value of mobNo
     */
    public String getMobNo() {
        return mobNo;
    }

    /**
     * Setter method for property <tt>mobNo</tt>.
     * 
     * @param mobNo value to be assigned to property mobNo
     */
    public void setMobNo(String mobNo) {
        this.mobNo = mobNo;
    }

    /**
     * 检查各个数据项
     */
    public void check() {

        CheckUtil.assertIsNumber(tradeId, "tradeId必须为数字");
        CheckUtil.assertRangeLength(tradeId, 6, 16, "tradeId必须为6-16位数字");
        CheckUtil.assertRegex(money, "^\\d{1,9}(\\.\\d{2})$", "必须保留两位小数");

        CheckUtil.assertNotNull(gate, "交易网关不能为空");

        CheckUtil.assertMaxLength(merPriv, 120, "私有域最长只能为120");

        CheckUtil.assertMaxLength(cardNo, 19, "卡号最长只能为120");

        if (StringUtils.isNotBlank(validDate)) {
            CheckUtil.assertLength(validDate, 4, "有效期只能为4位");
        }

        CheckUtil.assertLength(cvv2, 3, "cvv2只能为3位");

        CheckUtil.assertLength(idType, 2, "证件类型只能为2位");

        CheckUtil.assertMaxLength(idNo, 20, "证件号码最长只能为20位");

        CheckUtil.assertMaxLength(name, 20, "姓名最长只能为20位");

        if (gate == ChinapnrGate.CMB_TC) {
            CheckUtil.assertLength(mobNo, 11, "招行两通，必须填写手机号码");
        }
    }

    /**
     * 数据加密
     * 
     * @param baseUrl
     * @return
     */
    public String getChkValue(String baseUrl) {

        String memId = ChinapnrConfigUtil.getChinapnrInfo().getMemId();

        String check = PnrConstants.TRADE_VERSION + PnrConstants.TRADE_TELPAY + memId + tradeId
                       + money + gate.getGate() + merPriv + baseUrl
                       + ChinapnrInfo.TRADE_BACKGROUND_RESULT_URL;
        return Chinapnr.getSignValue(memId, check);
    }

    /**
     * 得到卡加密数据
     * 
     * @return
     */
    public String getCardInfo() {

        //信息数据项和格式为： CardNo + "|" + ValidDate + "|" + Cvv2 + "|" + IdType + "|" + IdNo + "|" + Name
        // 如果是招行两通模式，网关号为“Tc”，卡信息数据项和格式为： CardNo + "|" + ValidDate + "|" + Cvv2 + "|" + IdType + "|" + IdNo + "|" + Name + "|" + MobNo
        if (gate == ChinapnrGate.CMB_TC) {
            return Chinapnr.encData(cardNo + "|" + validDate + "|" + cvv2 + "|" + idType + "|"
                                    + idNo + "|" + name + "|" + mobNo);
        }

        return Chinapnr.encData(cardNo + "|" + validDate + "|" + cvv2 + "|" + idType + "|" + idNo
                                + "|" + name);
    }

}
